package main

import (
	"fmt"
	"io"
	"net"
	"sync"
	"time"
)

type Server struct {
	Ip string
	Port int

	//在线用户列表
	OnlineMap map[string]*User
	mapLock sync.RWMutex
	Message chan string
}

func NewServer(ip string,port int) *Server{
	//server:=&Server{Ip: ip,Port: port}
	// return server
	s:=new(Server)
	s.Ip=ip
	s.Port = port
	s.OnlineMap = make(map[string]*User)
	s.Message = make(chan string)
	return s

}
func (s *Server) ListenMessage()  {
	for {
		msg:= <-s.Message
		s.mapLock.Lock()
		for _,onlineUser := range s.OnlineMap {
			onlineUser.C <-msg
		}
		s.mapLock.Unlock()
	}

}
func (s *Server) BoradCast(user *User,msg string)  {
	sendMsg:="["+user.Addr +"]"+user.Name+":"+msg
	//这个协程在写数据
	s.Message<-sendMsg
}
func (s *Server) ReceiveClientMessage(conn net.Conn, user *User){
	buf:=make([]byte,4096)
	for{
		n,err:=conn.Read(buf)
		if n==0{
			user.Offline()
			return
		} else if err!=nil && err!=io.EOF{
			fmt.Println("conn Read err:",err)
		} else{
			msg:=string(buf[:n])
			user.DoMessage(msg)
		}

	}
}
func (s *Server) Handler(conn net.Conn) {
	fmt.Println("连接建立成功")

	//当前用户上线了
	user:=NewUser(conn,s)
	user.Online()
	//go s.ReceiveClientMessage(conn,user)
	isLive:=make(chan bool)
	go func() {
		buf:=make([]byte,4096)
		for{
			n,err:=conn.Read(buf)
			if n==0{
				user.Offline()
				return
			} else if err!=nil && err!=io.EOF{
				fmt.Println("conn Read err:",err)
			} else{
				msg:=string(buf[:n])
				user.DoMessage(msg)
				isLive <-true
			}

		}
	}()
	// 当前 handler阻塞
	for{
		select {
		case <-isLive:

		case <-time.After(time.Second*10):
			user.SendMessage("you have been forced offline")
			close(user.C)
			conn.Close()
			return
		}
	}

}
func (s *Server) Start()  {
	listener,err:=net.Listen("tcp",fmt.Sprintf("%s:%d",s.Ip,s.Port))
	if err!=nil{
		fmt.Println("net.Listen err:",err)
	}
	defer listener.Close()
	go s.ListenMessage()
	for{
		conn,err:=listener.Accept()
		if err!=nil{
			fmt.Println("listener accept err:",err)
			continue
		}
		go s.Handler(conn)
	}
}